<?php

namespace App\Services;

use App\Models\CompanyUser;
use App\Models\DossierCombination;
use App\Models\PartCompany;
use App\Models\PartCompanyUser;
use App\Models\Project;
use App\Models\ProjectClassify;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use PHPUnit\Util\Exception;

class ProjectService extends BaseService
{
    /**
     * 保存项目
     */
    public function saveData($params)
    {
        try {
            $userId     = user_id();
            $companyId  = company_id();
            $companyIds = CompanyUser::query()->where('user_id', $userId)->pluck('company_id'); //获取用户所在的有哪些公司

            if ($companyIds->isEmpty() && !is_super_admin()) {
                throw new Exception('无权操作！'); //如果没有所属公司，也不是超管
            }
            if (!is_super_admin() && !CompanyService::isCompanyAdminer($companyId, $userId)) {
                throw new Exception('您不是该公司管理员，无权创建项目');
            }
            $info = Project::query()->where('creator_id', $userId)->first();
            if ($info && !is_super_admin()) {
                throw new Exception('无权添加更多项目，请联系超管~');
            }
            if ($params['id']) {
                $project = Project::query()->find($params['id']);
            } else {
                $project = new Project();
            }
            $project->title           = format_str($params['title']); //项目名称
            $project->document_number = format_str($params['document_number']); //档案号
            $project->company_id      = $companyId; //项目所属单位
            $project->creator_id      = $userId; //项目在系统中的创建人
            $project->save();

            CommonService::addActionLog('新建项目', "数据ID:{$project->id}");

            return ['msg' => ''];
        } catch (Exception $exception) {
            return ['msg' => $exception->getMessage()];
        }
    }

    /**
     * 更新
     */
    public function updateData($params, $id)
    {
        $newTitle          = format_str($params['title']);
        $newDocumentNumber = format_str($params['document_number']);

        $project                  = Project::query()->find($id);
        $project->title           = $newTitle; //项目名称
        $project->document_number = $newDocumentNumber; //档案号
        $project->template_id     = $params['template_id']; //档案号
        $project->combination_id  = $params['combination_id']; //档案号
        $detail                   = "数据ID:{$id}";
        if ($project->title != $newTitle) {
            $detail = "数据ID:{$id},项目名称由{$project->title}修改为{$newTitle}";
        }
        if ($project->document_number != $newDocumentNumber) {
            $detail = "数据ID:{$id},项目代码由{$project->document_number}修改为{$newDocumentNumber}";
        }
        CommonService::addActionLog('更新项目', $detail);

        return $project->save();
    }

    /**
     * 返回项目下的所有用户。
     */
    public function users(int $project_id)
    {
        $project = Project::query()->with('users:id,nickname,status')->find($project_id);
        $userIds = [];

        if (empty($project)) return $userIds;

        return $project->toArray()['users'];
    }

    /**
     * 获取项目列表数据
     * 一个公司下面会存在多个项目，用户在哪个项目就看到哪个，没在的话看不到
     */
    public function getList($request, $perPage = 0): array
    {
        if (is_company_admin() || is_super_admin()) { //如果是公司管理员或者超管，可看该公司下的全部项目
            $thisQuery = Project::query()->with(['classifyTemplate', 'combination'])->where('company_id', company_id());
        } else {
            $projectIds = self::getLinkProjectIds(); //仅获取当前公司里和用户关联的项目
            $thisQuery  = Project::query()->with(['classifyTemplate', 'combination'])->whereIn('id', $projectIds);
        }
        if ($request->filled('keyword')) {
            $keyword = $request->input('keyword');
            $thisQuery->where('id', '=', $keyword)->orWhere('title', 'like', "%{$keyword}%");
        }
        $list = $thisQuery->paginate($perPage);
        if ($list->isEmpty()) return [];
        $list = $list->toArray();
        foreach ($list['data'] as &$val) {
            $val['template_id']            = to_int($val['template_id']);
            $val['combination_id']         = to_int($val['combination_id']);
            $val['part_company_count']     = PartCompany::query()->where('project_id', $val['id'])->count();
            $val['project_bt_count']       = self::getProjectBtCount($val['id']);
            $val['is_show_project_search'] = 0;
            $val['created_at']             = Carbon::parse($val['created_at'])->format('Y-m-d');
            $val['created_days']           = Carbon::parse($val['created_at'])->diffInDays(now()); //已创建天数
            if (is_super_admin() || is_company_admin() || self::isProjectOwner($val['id'])) {
                $val['is_show_project_search'] = 1;
            }
        }
        return $this->removeNoUsedPageParams($list);
    }

    /**
     * 获取项目总案卷
     *
     * @param $projectId
     * @return int|mixed
     * @author: lxk
     * @date: 2024/5/10 17:55
     */
    public static function getProjectBtCount($projectId)
    {
        return PartCompany::query()->where('project_id', $projectId)->sum('book_title_count');
    }

    /**
     * 当前用户是不是业主
     *
     * @param $projectId
     * @return bool
     * @author: lxk
     * @date: 2024/5/7 14:35
     */
    public static function isProjectOwner($projectId): bool
    {
        $partCompanyId = PartCompany::query()
            ->where('project_id', $projectId)
            ->where('type', 1) //查出项目下的业主
            ->value('id');

        $info = '';
        if ($partCompanyId) {
            $info = PartCompanyUser::query()
                ->where('user_id', user_id())
                ->where('part_company_id', $partCompanyId)
                ->where('status', 1)
                ->first();
        }

        return !empty($info);
    }

    /**
     * 获取用户关联的项目
     */
    public static function getLinkProjectIds()
    {
        $ids        = Project::query()->where('company_id', company_id())->pluck('id'); //当前公司下有哪些项目
        $projectIds = DB::table('project_user') //哪些项目跟我有关系
        ->whereIn('project_id', $ids)
            ->where('user_id', user_id())
            ->pluck('project_id');
        if ($projectIds->isNotEmpty()) {
            $projectIds = $projectIds->toArray();
        } else {
            $projectIds = [];
        }
        return $projectIds;
    }

    /**
     * 匹配和设置分类目录模板
     */
    public function setClassifyTemplateId($projectId, $templateId)
    {
        $project              = Project::query()->find($projectId);
        $project->template_id = $templateId;

        if (!$project->save()) {
            return false;
        }
        CommonService::addActionLog('匹配和设置分类目录模板', "项目ID:{$projectId};模板ID:{$templateId}");

        return true;
    }

    /**
     * 获取一条数据信息
     */
    public static function getInfo($id)
    {
        return Project::query()->find($id);
    }

    /**
     * 关联案卷模板组合
     */
    public function relateCombination($params)
    {
        $project                 = Project::query()->find($params['project_id']);
        $project->combination_id = $params['combination_id'];

        CommonService::addActionLog('匹配和设置分类目录模板', "项目ID:{$params['project_id']}; 卷模板组合ID:{$params['combination_id']}");

        return $project->save();
    }

    /**
     * 回收站数据
     */
    public function getRecycles($request): array
    {
        $thisQuery = Project::onlyTrashed();

        if ($request->filled('keyword')) { //判断参数是否存在并且不为空
            $keyword = $request->input('keyword');
            $thisQuery->where('title', 'like', "%{$keyword}%")->orWhere('id', '=', $keyword); //由于不同的表字段不同，所以单独拿出来
        }

        return $this->formatRecycleData($request, $thisQuery);
    }

    /**
     * 先获取对应的案卷模板组合，再获取是哪个案卷模板
     */
    public function getDossierCombination($partCompanyId)
    {
        $projectId = PartCompany::query()->where('id', $partCompanyId)->value('project_id');

        return Project::query()->where('id', $projectId)->value('combination_id');
    }

    /**
     * 判断当前登录用户是项目下的那个单位
     */
    public static function partCompanyUser($projectId)
    {
        $partCompanyIds = PartCompany::query()->where('project_id', $projectId)->pluck('id');
        if ($partCompanyIds->isEmpty()) return false;

        $partCompanyIds = $partCompanyIds->toArray();

        $partCompanyIds = PartCompanyUser::query()
            ->whereIn('part_company_id', $partCompanyIds)
            ->where('user_id', user_id())
            ->pluck('part_company_id');

        if ($partCompanyIds->isEmpty()) return [];
        $partCompanyIds = $partCompanyIds->isNotEmpty() ? $partCompanyIds->toArray() : [];

        return [
            'type'            => PartCompany::query()->where('id', $partCompanyIds[0])->value('type'),
            'part_company_id' => $partCompanyIds[0],
            'ids'             => $partCompanyIds,
        ];
    }

    /**
     * 获取【检索阶段】项目分类
     */
    public function getProjectClassifies($projectId)
    {
        $templateId = Project::query()->where('id', $projectId)->value('template_id'); //取项目使用的模板

        $partCompanyIds = PartCompany::query() //获取项目的参见单位
        ->where('project_id', $projectId)
            ->pluck('id')
            ->toArray();

        $projectClassifies = ProjectClassify::query()
            ->where('template_id', $templateId)  //基础分类目录
            ->orWhereIn('part_company_id', $partCompanyIds) //各参见单位后期自己加的
            ->select('id', 'title', 'classify_id', 'parent_id')
            ->get();

        return $projectClassifies->isNotEmpty() ? $projectClassifies->toArray() : [];
    }

    /**
     * 从仓库下载代码后，首次登录会创建项目用到的文件夹，避免了手动创建文件夹带来的繁琐
     * 对于从创建文件夹
     */
    public static function createProDirectory()
    {
        if (!File::exists('storage/excels')) {
            File::makeDirectory('storage/cutPdf', 0777); //分割后的pdf
            File::makeDirectory('storage/downTemplates', 0777); //导出案卷封面、备考表用的底模板
            File::makeDirectory('storage/excels', 0777);
            File::makeDirectory('storage/excelToPdf', 0777);
            File::makeDirectory('storage/files', 0777);
            File::makeDirectory('storage/images', 0777);
            File::makeDirectory('storage/pageTxts', 0777);  //导出的案卷页码
            File::makeDirectory('storage/pdfs', 0777);
            File::makeDirectory('storage/words', 0777); //导出案卷封面、备考表
        }
    }
}
